// core/String.h

#ifndef _CORE_String_H_
#define _CORE_String_H_

// typedefs
typedef void * (*AllocationFunc)( int iSize );
typedef void   (*FreeFunc)( void * pData );

namespace CORE
{

class String
{
public:
	String() : m_pBuffer(0), m_iSize(0), m_bOwnsBuffer(false) {}

	String(const String& Source, bool bDuplicateBuffer = true) :
		m_pBuffer(0),
		m_iSize(0),
		m_bOwnsBuffer(false)
	{
		SetString(Source.m_pBuffer, Source.GetLength(), bDuplicateBuffer);
	}
	String(const char *pString, int iSize = -1, bool bDuplicateBuffer = true) :
		m_pBuffer(0),
		m_iSize(0),
		m_bOwnsBuffer(false)
	{
		SetString(pString, iSize, bDuplicateBuffer);
	}
	virtual ~String()
	{
		DeleteString();
	}

	// Acessors
	char *					GetBufferPtr() {
		return m_pBuffer;
	}
	const char *			GetBufferPtr() const {
		return m_pBuffer;
	}

	void					SetLength(int iSize);
	int						GetLength() const {
		return m_iSize;
	}

	int						GetNumCharacters() const {
		return m_iSize - 1;
	}

	// APIs
	static void				SetAllocationFunc(AllocationFunc pAllocFunc) {
		s_pAllocationFunc = pAllocFunc;
	}
	static void				SetFreeFunc(FreeFunc pFreeFunc) {
		s_pFreeFunc = pFreeFunc;
	}

	void					DeleteString();
	void					SetString(const String &Source) {
		SetString(Source.m_pBuffer, Source.m_iSize);
	}
	void					SetString(const char *pString, int iSize=-1, bool bDuplicateBuffer = true);
	void					SetStringVA(const char *pString, ...);

	// Operator overloads
	const String &			operator=(const String & that) {
		SetString(that);
		return *this;
	}
	String					operator+(const String& that) const;

	bool					operator==(const String & that) const;
	bool					operator!=(const String & that) const;

protected:

	// Default memory allocation and freeing functions.
	static void *	Allocate( int iSize );
	static void		Free( void * pData );

	static AllocationFunc 	s_pAllocationFunc;
	static FreeFunc 		s_pFreeFunc;

	static const char *		s_pNullString;

	char *	m_pBuffer;
	int		m_iSize;
	bool	m_bOwnsBuffer;
};

}; // namespace CORE


#endif